import {BaseContext, Constructor} from "./BaseContext";

class SingletonContext extends BaseContext {
	public get contentName() { return "Singleton"; }
}

class SingletonUtils {

	public static context = new SingletonContext();

	// static singletons = []
	//
	// public static add<T>(clazz: Constructor<T>, value: T) {
	// 	const ori = this.find(clazz);
	// 	if (!ori) this.singletons.push({clazz, value});
	// 	else ori.value = value;
	//
	// 	console.log("[ADD] ", {clazz, value});
	// }
	// public static remove<T>(clazz: Constructor<T>) {
	// 	const ori = this.find(clazz);
	// 	if (ori) ori.value = null;
	//
	// 	console.error("[REMOVE] ", {clazz});
	// }
	// public static instance<T>(clazz: Constructor<T>) : T {
	// 	if (!clazz) return null;
	//
	// 	const res = this.find(clazz)?.value;
	// 	if (!res) console.error("[GET] ", {clazz, res});
	//
	// 	return res;
	// }
	//
	// private static find<T>(clazz: Constructor<T>): {clazz: Constructor<T>, value: T} {
	// 	return this.singletons.find(s => s.clazz == clazz);
	// }
}

export function singleton<T>(clazz: Constructor<T>) {
	SingletonUtils.context.create(clazz, new clazz());
}

export function singletonValue<T>(clazz: Constructor<T>) {
	return (target, key) => {
		console.log("[USE] ", {clazz, target, key});
		target[key] = getSingleton(clazz);
	}
}
export function singletonGetter<T>(clazz: Constructor<T>) {
	return (target, key, desc) => {
		desc.value = (): T =>
			target[key + '_CACHE'] ||= getSingleton(clazz)
	};
}

export function getSingleton<T>(clazz: Constructor<T>) {
	// console.error("[USE] ", clazz);
	return SingletonUtils.context.instance(clazz);
}
